package com.sc.nft.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.sc.nft.dao.SmsCodeRecordDao;
import com.sc.nft.dao.UserInfoDao;
import com.sc.nft.dto.SendMessageOneDataReq;
import com.sc.nft.dto.SendMessageOneReq;
import com.sc.nft.entity.SmsCodeRecord;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.enums.SendSMSEnum;
import com.sc.nft.enums.UserAccoutTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.feign.SmsFeignClient;
import com.sc.nft.pool.UserPool;
import com.sc.nft.req.TencentSendSmsReq;
import com.sc.nft.service.SmsCodeRecordService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.Result;
import com.sc.nft.util.CheckAccountUtil;
import com.sc.nft.util.MailUtils;
import com.sc.nft.vo.LdySendOneVO;
import com.sc.nft.vo.TencentSendVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务接口实现
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2022-05-29 10:53:23
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SmsCodeRecordServiceImpl implements SmsCodeRecordService {

    private final UserInfoDao userInfoDao;
    private final SmsCodeRecordDao smsCodeRecordDao;
    private final SmsFeignClient smsFeignClient;


    @Value("${qcloud.sms.secretId}")
    private String secretId;
    @Value("${qcloud.sms.secretKey}")
    private String secretKey;

    @Override
    public HashMap<String, String> sendRegisteSms(String userAccount, Integer type, Integer types) {

        checkuserAccount(userAccount);

        if(type == 13){
            //查询数据库中用户是否存在
            UserInfo user = userInfoDao.loginByTel(userAccount);

            Assert.isFalse(ObjectUtil.isEmpty(user) || user.getIsCancellation(),()->new GlobalRunTimeException(ErrorCode.ACCOUNT_NOT_EXIST));
            Assert.isFalse(user.getIsFreeze(),()->new GlobalRunTimeException(ErrorCode.ACCOUNT_HAS_BEEN_FROZEN));

            return smsCodes(UserAccoutTypeEnum.USER_LOGIN.getCode(), userAccount, type);
        }

        Integer num = smsCodeRecordDao.getNumBerByUserTelAndToDay(userAccount);
        if(num >= 5){
            throw new GlobalRunTimeException(ErrorCode.TOO_MANY_REGISTRATIONS_SENT_PLEASE_CONTACT_THE_ADMINISTRATOR);
        }

        if (!CheckAccountUtil.checkPhone(userAccount)) {
            throw new GlobalRunTimeException(ErrorCode.INCORRECT_ACCOUNT_FORMAT);
        }

        UserInfo userInfo = userInfoDao.getOneByUserTel(userAccount);
        if (type == SendSMSEnum.REGISTER.getCode() && ObjectUtil.isNotEmpty(userInfo)) {
            throw new GlobalRunTimeException(ErrorCode.ACCOUNT_EXIST);
        }

        if (type == SendSMSEnum.FORGOT_PASSWORD.getCode() && ObjectUtil.isEmpty(userInfo)) {
            throw new GlobalRunTimeException(ErrorCode.ACCOUNT_NOT_EXIST);
        }

        return smsCodes(UserAccoutTypeEnum.USER_TEL.getCode(), userAccount, type);
    }


    @Override
    public HashMap<String, String> getSmsOtherCode(String userAccount, Integer type, Integer types) {

        checkuserAccount(userAccount);

        if (StrUtil.isEmpty(userAccount)) {
            UserInfo user = UserPool.getUser();
            userAccount = user.getUserTel();
        }

        return smsCodes(UserAccoutTypeEnum.USER_TEL.getCode(), userAccount, type);
    }

    @Override
    public HashMap<String, String> getAdminCode(String userAccount, Integer type, Integer types) {
        if (StrUtil.isEmpty(userAccount)) {
            UserInfo user = UserPool.getUser();
            userAccount = user.getUserTel();
        }

        return smsCodes(types, userAccount, type);
    }

    @Override
    public void checkuserAccount(String userAccount) {
        SmsCodeRecord smsCodeRecord = smsCodeRecordDao.findLastRecordByUserAccount(userAccount);
        if (ObjectUtil.isNotEmpty(smsCodeRecord)) {
            long time = smsCodeRecord.getCreateTime().getTime();
            long now = System.currentTimeMillis();
            if (now - time <= 60000l) {
                throw new GlobalRunTimeException(ErrorCode.DO_NOT_REFETCH_WITHIN_A_MINUTE);
            }
        }

    }


    /**
     * 发送验证码并加入记录
     *
     * @param types
     * @param userAccount
     * @param type
     * @return
     */
    private HashMap<String, String> smsCodes(Integer types, String userAccount, Integer type) {
        String status = "";
        Map<String, Object> smsReturnMap = new HashMap<>();
        String smsCode = String.valueOf(RandomUtil.randomInt(100000, 999999));
        if (types == 1 || types == 3) {
            //status = SendSMS.send(userAccount, smsCode);
            if (sendTemplate(userAccount,"1841485",new String[]{smsCode})) {
                smsReturnMap.put("statusMsg", "success");
                smsReturnMap.put("isSend", "y");
            } else {
                smsReturnMap.put("statusMsg", "fail");
                smsReturnMap.put("isSend", "n");
            }
        } else {
            try {
                MailUtils.sendMail(userAccount, "[" + "玛特宇宙" + "]", "您的验证码是 : " + smsCode + " 5分钟后失效，请勿泄露给他人。如非本人操作，请忽略此信息。");
                smsReturnMap.put("isSend", "y");
            } catch (Exception e) {
                smsReturnMap.put("isSend", "n");
                e.printStackTrace();
            }
        }

        SmsCodeRecord smsCodeRecord = new SmsCodeRecord();
        smsCodeRecord.setUserTel(userAccount);
        smsCodeRecord.setType(type);
        smsCodeRecord.setIsSend(smsReturnMap.get("isSend") + "");
        smsCodeRecord.setCodes(smsCode);
        smsCodeRecord.setResult(smsReturnMap.toString());
        smsCodeRecord.setTypeName(SendSMSEnum.getValue(type));
        smsCodeRecord.setStatusMsg(smsReturnMap.get("statusMsg") + "");
        smsCodeRecord.insert();
        smsReturnMap.put("id", smsCodeRecord.getId());
        log.info("smsReturnMap,{}",smsReturnMap);
        if (!"y".equals(smsReturnMap.get("isSend") + "")) {
            throw new GlobalRunTimeException(ErrorCode.SMS_FAIL);
        }

        HashMap<String, String> map = new HashMap<>();
        map.put("isSend", smsReturnMap.get("isSend").toString());
        map.put("smsId", smsReturnMap.get("id").toString());

        return map;
    }

    @Override
    public boolean sendTemplate(String phoneNumber, String templateId, String[] data) {
        TencentSendSmsReq tencentSendSmsReq = new TencentSendSmsReq();
        tencentSendSmsReq.setPhoneNumber(phoneNumber);
        tencentSendSmsReq.setTemplateId(templateId);
        tencentSendSmsReq.setData(data);
        try {
            Result<TencentSendVO> tencentSendVOResult = smsFeignClient.tencentSend(tencentSendSmsReq);
            if (!tencentSendVOResult.getCode().equals(0) || ObjectUtil.isNull(tencentSendVOResult.getData())) {
                return false;
            }
            return tencentSendVOResult.getData().getSuccess();
        } catch (Exception var6) {
            log.error("短信发送异常:" + var6.getMessage(), var6);
            return false;
        }
    }


}